package com.hc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hc.common.bean.PageBean;
import com.hc.common.enums.ResultEnum;
import com.hc.common.utils.JsonUtil;
import com.hc.constant.CategoryConst;
import com.hc.constant.PageConst;
import com.hc.constant.RedisConst;
import com.hc.domain.Category;
import com.hc.ex.GlobalException;
import com.hc.mapper.CategoryMapper;
import com.hc.query.ProductCategoryCondition;
import com.hc.res.CategoryItem;
import com.hc.service.CategoryService;
import com.hc.trans.CategoryTrans;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hecai
 */
@Service
@CacheConfig(cacheManager = "cacheManager")
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public PageBean<CategoryItem> queryByCondition(ProductCategoryCondition condition) {
        if (condition == null) {
            throw new GlobalException(ResultEnum.PARAM_ERROR);
        }

        final Long current = condition.getCurrent() == null ? 1 : condition.getCurrent();
        final Integer pageSize = condition.getPageSize() == null ? PageConst.DEFALUT_PAGE_SIZE : condition.getPageSize();
        IPage<CategoryItem> page = new Page<>(current, pageSize);

        baseMapper.selectListByCondition(page, condition);

        PageBean<CategoryItem> categoryItemPageBean = PageBean.init(page);
        return categoryItemPageBean;
    }

    @Override
    @Cacheable(value = RedisConst.CATEGORY, key = "#key", condition = "#flag==true")
    public List<CategoryItem> listAllCategories(String key, Boolean flag) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<Category>()
                .select("id", "name", "priority", "pid")
                .eq("status", CategoryConst.Status.ok);
        List<Category> categoryList = baseMapper.selectList(queryWrapper);
        List<CategoryItem> categoryItemList = CategoryTrans.MAPPER.categoryList2categoryItemList(categoryList);
        //找到一级分类（以子列表的形式包含二级分类）
        List<CategoryItem> res = categoryItemList.stream()
                .filter(item -> item.getPid() == null)
                .peek(item -> item.setChildren(getChildren(item, categoryItemList)))
                .sorted(Comparator.comparingInt(CategoryItem::getPriority))
                .collect(Collectors.toList());
        System.out.println(JsonUtil.obj2String(res));
        return res;
    }

    private List<CategoryItem> getChildren(CategoryItem category, List<CategoryItem> all) {
        List<CategoryItem> childList = all.stream()
                .filter(item -> category.getId().equals(item.getPid()))
                .peek(item -> item.setChildren(getChildren(item, all)))
                .sorted(Comparator.comparingInt(CategoryItem::getPriority))
                .collect(Collectors.toList());
        return childList;
    }
}
